﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using Asteroids.Physics;

using Geometria;
using Geometria.FigurasPlanas;

using Tao.FreeGlut;
using Tao.OpenGl;

namespace Asteroids
{
    public partial class Form1 : Form
    {
        #region Fields

        private ElementosDelJuego elementos;
        private List<Keys> teclasActivas;

        #endregion Fields

        #region Constructors

        public Form1()
        {
            InitializeComponent();

            simpleOpenGlControl1.InitializeContexts();

            this.InitializeContext();
        }

        #endregion Constructors

        #region Properties

        public ElementosDelJuego Elementos
        {
            get
            {
                if (elementos == null)
                    elementos = new ElementosDelJuego();
                return elementos;
            }
        }

        public List<Keys> TeclasActivas
        {
            get { return teclasActivas; }
            set
            {
                if (teclasActivas == null)
                    teclasActivas = new List<Keys>();
                teclasActivas = value;
            }
        }

        #endregion Properties

        #region Methods

        private void AgregarTecla(Keys key)
        {
            if (!teclasActivas.Contains(key))
                teclasActivas.Add(key);
        }

        private void ComprobarColisiones()
        {
        }

        private Circulo CrearCirculo()
        {
            Punto punto;
            Vector eje;
            Circulo c;

            punto = new Punto(0.5, 0.5, 0.1);
            eje = new Vector(0.0, 0.0, 1.0);

            c = new Circulo(punto, eje, 2.0);

            return c;
        }

        private Triangulo CrearRectangulo()
        {
            Punto p1, p2, p3;
            Triangulo t1;

            p1 = new Punto(0.5, 1.0, 0.0);
            p2 = new Punto(0.0, 0.0, 0.0);
            p3 = new Punto(1.0, 0.0, 0.0);
            t1 = new Triangulo(p1, p2, p3);

            return t1;
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            try
            {
                AgregarTecla(e.KeyCode);
            }
            catch (System.Exception ex)
            {

            }
        }

        private void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            try
            {
                QuitarTecla(e.KeyCode);
            }
            catch (System.Exception ex)
            {

            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                this.timer1.Interval = Physics.Objeto.LatenciaMilisegundos;
                this.timer1.Start();
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// Establece los parametros iniciales del contexto de dibujo OpenGL
        /// </summary>
        private void InitializeContext()
        {
            Gl.glClearColor(0f, 0f, 0f, 0f);
            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glLoadIdentity();
            Gl.glOrtho(-10.0, 10.0, -10.0, 10.0, -1.0, 1.0);
        }

        private void ModificarObjetos()
        {
            if (this.TeclasActivas.Contains(Keys.Up))
                this.Elementos.Nave.Acelerar();

            if (this.TeclasActivas.Contains(Keys.Down))
                this.Elementos.Nave.Acelerar();
        }

        private void MoverObjetos()
        {
            foreach (Physics.Asteroide asteroide in this.Elementos.Asteroides)
                asteroide.IterarMovimiento();

            foreach (Physics.Misil misil in this.Elementos.Misiles)
                misil.IterarMovimiento();

            foreach (Physics.Projectil projectil in this.Elementos.Projectiles)
                projectil.IterarMovimiento();

            foreach (Physics.Premio premio in this.Elementos.Premios)
                premio.IterarMovimiento();

            this.Elementos.Nave.IterarMovimiento();
        }

        private void QuitarTecla(Keys key)
        {
            teclasActivas.Remove(key);
        }

        private void simpleOpenGlControl1_Load(object sender, EventArgs e)
        {
        }

        private void simpleOpenGlControl1_Paint(object sender, PaintEventArgs e)
        {
            try
            {
                Gl.glClear(Gl.GL_COLOR_BUFFER_BIT);
                Gl.glColor3f(1f, 1f, 1f);

                foreach (Physics.Asteroide asteroide in Elementos.Asteroides)
                    asteroide.Graficar();

                foreach (Physics.Premio premio in Elementos.Premios)
                    premio.Graficar();

                foreach (Physics.Misil misil in Elementos.Misiles)
                    misil.Graficar();

                foreach (Physics.Projectil projectil in Elementos.Projectiles)
                    projectil.Graficar();

                Elementos.Nave.Graficar();

                Gl.glFlush();
            }
            catch (System.Exception ex)
            {

            }
        }

        private void simpleOpenGlControl1_SizeChanged(object sender, EventArgs e)
        {
            this.InitializeContext();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            MoverObjetos();

            ComprobarColisiones();

            ModificarObjetos();
        }

        #endregion Methods
    }
}